﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Gp.Scripts.Core;
using Gp.Scripts.GUI;
using UnityEngine;


namespace Gp.Scripts.Data
{
    public struct BuffIconRenderInfo
    {
        public string BuffName;
        public string Description;
        public Sprite Icon;
        public int Duration;
    }


    public interface IAdditiveBuff
    {
        public int Level { get; }
    }


    public interface IResourceBuff : IAdditiveBuff { }


    /// Buff用于持续性效果实现，包括属性修饰、行为禁止、逻辑触发
    /// <para>逻辑触发：时间触发（回合数）、行动触发（攻击、移动、使用技能）、条件触发（造成过伤害）</para>
    /// <para>行为禁止：如攻击禁止、施法禁止、移动禁止</para>
    /// <para>属性修饰：常规属性修饰</para>
    [Serializable]
    public abstract class BaseBuff : IBonusProvider, ILogicEntity
    {
        public abstract BuffEntityConfig EntityConfig { get; }


        public UnitBuffCom UnitBuffCom { get; private set; }

        public BaseUnit Unit => UnitBuffCom.Unit;

        private List<IWeakRuleWrapper> _rules = new();

        protected void RegisterRule<T>(WeakRuleWrapper<T> rule) where T : class, IActionRequest
        {
            Model.RegisterRule(rule);
            _rules.Add(rule);
        }

        protected void UnregisterAction<T>(WeakRuleWrapper<T> rule) where T : class, IActionRequest
        {
            Model.UnRegisterRule(rule);
            _rules.RemoveAll(i => i.Name == rule.Name);
        }


        public virtual void Apply(UnitBuffCom unitBuffCom)
        {
            UnitBuffCom = unitBuffCom;
            if (Unit.TryGetSubObject<UnitBuffFxContainer>(out var buffContainer))
            {
                buffContainer.Add(this, EntityConfig.buffFx);
            }


            Init();
            OnBuffApply();
        }


        /// <summary>
        ///  调用进行初始化，执行时间在OnBuffApply前
        /// </summary>
        protected abstract void Init();


        protected virtual void OnBuffApply() { }


        /// <summary>
        /// 回合开始更新逻辑
        /// </summary>
        public virtual IEnumerator TurnStartUpdate()
        {
            yield break;
        }

        /// <summary>
        /// 回合结束更新逻辑
        /// </summary>
        public virtual IEnumerator TurnEndUpdate()
        {
            yield break;
        }

        public virtual IEnumerator SmallTurnStartUpdate(TurnState state)
        {
            yield break;
        }

        public virtual IEnumerator SmallTurnEndUpdate(TurnState state)
        {
            yield break;
        }


        // /// <summary>
        // /// 帧更新逻辑
        // /// </summary>
        // public virtual void OnUpdate() { }


        /// <summary>
        ///  图标信息渲染逻辑
        /// </summary>
        /// <returns></returns>
        public virtual BuffIconRenderInfo OnIconRender()
        {
            return new BuffIconRenderInfo()
            {
                Icon        = EntityConfig.Icon,
                BuffName    = EntityConfig.ItemName,
                Description = EntityConfig.Description,
            };
        }

        public void TextEffect(BaseUnit unit, string text)
        {
            Global.Get<GridBattleGUISystem>().PlayFloatingText(unit, text);
        }

        public void TextEffect(string text)
        {
            TextEffect(Unit, text);
        }


        public virtual IEnumerable<BonusNumber> Bonus()
        {
            return Array.Empty<BonusNumber>();
        }


        /// 当应用相同Buff时，会调用叠加
        /// 最终会保留先来者
        /// 当进行叠加时，不会调用Apply
        public virtual void OnBuffAdditive(BaseBuff other) { }


        /// <summary>
        /// 消耗buff
        /// </summary>
        public virtual void Consume()
        {
            Destroy();
        }


        /// <summary>
        /// 调用移除Buff
        /// </summary>
        public void Remove()
        {
            if (Unit.TryGetSubObject<UnitBuffFxContainer>(out var buffContainer))
            {
                buffContainer.Remove(this);
            }

            OnBuffFade();
        }

        protected virtual void OnBuffFade() { }


        /// <summary>
        /// 调用移除此Buff
        /// </summary>
        public void Destroy()
        {
            // 移除注册规则
            _rules.ForEach(r => Model.UnRegisterRule(r));
            _rules.Clear();
            UnitBuffCom?.RemoveBuff(this);
        }


        public IEnumerable<BuffTags> BuffTags()
        {
            return EntityConfig.tags;
        }

        /// <summary>
        /// 一个单位只能拥有一个同名Buff。
        /// </summary>
        /// <returns></returns>
        public string BuffId => GetBuffIdProcess(GetType());


        public RulesModel Model => Global.Get<BattleSystemConfig>().RulesModel;

        public static string GetBuffId<T>() where T : BaseBuff
        {
            return GetBuffIdProcess(typeof(T));
        }

        private static string GetBuffIdProcess(Type type)
        {
            var foo = type.GetCustomAttribute<BuffGroupAttribute>();
            return foo != null ? foo.Id : type.Name;
        }
        
        
        public virtual ILogicEntity GetBonusProviderInfo()
        {
            return this;
        }

        public IEntityConfig GetConfig()
        {
            return EntityConfig;
        }
    }


    public abstract class BaseBuff<T> : BaseBuff where T : BuffEntityConfig
    {
        public T BuffData { get; private set; }

        public override BuffEntityConfig EntityConfig => BuffData;


        public sealed override void Apply(UnitBuffCom unitBuffCom)
        {
            if (BuffData == null)
            {
                var model = Global.Get<BattleSystemConfig>().RulesModel;
                BuffData = model.GetData<T>();
            }

            base.Apply(unitBuffCom);
        }


        protected BaseBuff(T buffData)
        {
            BuffData = buffData;
        }


        protected BaseBuff() { }
    }


    /// <summary>
    /// 带有该注解的buff的id相同
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    public class BuffGroupAttribute : Attribute
    {
        public string Id;

        public BuffGroupAttribute(string id)
        {
            Id = id;
        }
    }
}